/*! 
\file Algorithm.h
\brief Contains definition of Algorithm class.
\ingroup Algorithm
*/

/*
Algorithm supports us with a base class for our own algorithms. The actual algorithm itself should be implemented in virtual void run()
*/

#ifndef ALGORITHM_H
#define ALGORITHM_H

#include"Container.h"
#include"Graph.h"

class Action;
class ContainerElementAction;

#include<QObject>
#include<QList>

/*!
\defgroup Algorithm Algorithm Module
This module revolves around the implementation of the Algorithm and gathering data about it. Closely linked to \ref Action and \ref Graph.
*/

/*! 
\class Algorithm 
\brief Custom algorithms should inherit this class and implement run function. 
\ingroup Algorithm
*/
class Algorithm: private QObject{
Q_OBJECT
public:
	Algorithm( Graph *graph );//!< Constructor. Must contain a graph initialized for usage by this algorithm.
	//This graph is NOT deleted here. It should be deleted by the user in its own class.
	virtual ~Algorithm(){ ; }//!< Destructor.
	
	//Algorithm to be implemented here.
	virtual void run() = 0;//!< Users should implement their algorithm in this function.
	
	void containerAdd();//!< Create one new Container at the end of the list.
	void containerPop();//!< Removes Container that was added last.
	int containerCount()const;//!< Returns amount of used Containers.
	
	Container &container( int i );//!< Returns i'th Container.
	
	Graph *graph()const{ return m_graph; }//!< Returns the graph we're working on.
	
	void comment( QString c );//!< Output a comment during execution of the Algorithm.
protected:
	//Can be called by classes that inherit Algorithm. Will highlight an edge/node.
	void highlight( const Node &node );//!< Highlight a Node.
	void highlight( const Edge &edge );//!< Highlight an Edge.
	
	Node *getNode( QString comment );//!< Request user for Node input
	Edge *getEdge( QString comment );//!< Reauest user for Edge input
private:
	friend class AlgorithmVisualizer;
	QList<Container> m_containers;
	Graph *m_graph;
	QList<Action*> m_actions;
	Action *_popAction();
private slots:
	void _reportAction( Action *action );
	void _reportAction( ContainerElementAction *action );
};

#endif

